#include "swpmergegraphicitem.h"

#include "../../documents/data/graphicdata.h"
#include "../../undo/basicitemcommands.h"
#include "../../utils/undomanager.h"
#include "graphicitemcommon.h"

#include <QtGui/QGraphicsScene>

using namespace core;
using namespace gui;
using namespace swp;

SwpMergeGraphicItem::SwpMergeGraphicItem(QGraphicsItem* parent) :
    AbstractPolygonGraphicItem(parent)
{
    QPolygonF polygon;
    polygon << QPointF(25, 0) << QPointF(50, 25) << QPointF(25, 50)
        << QPointF(0, 25);

    setPolygonF(polygon);

    setFlags(flags() | QGraphicsItem::ItemIsMovable |
        QGraphicsItem::ItemIsSelectable);

    setSingleConnectPointMode(true);
}

SwpMergeGraphicItem::~SwpMergeGraphicItem()
{

}
bool SwpMergeGraphicItem::supportsConnection(
    const ConnectionData& connection) const
{
    bool ret = false;

    const int type = connection.From != 0 ? connection.From->type() :
        INVALID_TYPE;

    const QList<ConnectionData> _connections = connections();

    const bool predecision = (connection.To == this ?
        incomingConnectionSize(_connections) < 2 : true) &&
        (connection.From == 0 ?
             outgoingConnectionSize(_connections) < 1 : true);

    ret = predecision && (connection.From == 0 ||
        ((type == SWP_ACTIVITY_ITEM || type == SWP_JOIN_ITEM ||
        type == SWP_SPLIT_ITEM) &&
            connection.ConnectionId == CONNECTION_ACTIVITY &&
            !containsSameConnection(connection, _connections)));

    return ret;
}

int SwpMergeGraphicItem::type() const
{
    return SWP_MERGE_ITEM;
}

QString SwpMergeGraphicItem::name() const
{
    return QObject::tr("Merge");
}

IEditorItem* SwpMergeGraphicItem::copy() const
{
    return new SwpMergeGraphicItem(0);
}

QList<Property> SwpMergeGraphicItem::properties() const
{
    QList<Property> ret;

    return ret;
}

QVariant SwpMergeGraphicItem::propertyValue(
    const QString& propertyName) const
{
    QVariant ret;

    return ret;
}

void SwpMergeGraphicItem::propertyChanged(const QString& property,
    const QVariant& newValue, bool silent)
{

}

QVariantList SwpMergeGraphicItem::optionList(
    const QString& propertyName) const
{
    QVariantList ret;

    return ret;
}

QVariantList SwpMergeGraphicItem::autocomplete(
    const QString& propertyName) const
{
    QVariantList ret;

    return ret;
}

QList<QPointF> SwpMergeGraphicItem::scalePoints() const
{
    QList<QPointF> ret;

    ret << QPointF(25, 0) << QPointF(50, 25) << QPointF(25, 50)
        << QPointF(0, 25);

    return ret;
}

QList<QPointF> SwpMergeGraphicItem::connectPoints() const
{
    QList<QPointF> ret;

    ret << QPointF(25, 0) << QPointF(50, 25) << QPointF(25, 50)
        << QPointF(0, 25);

    return ret;
}

QList<QPointF> SwpMergeGraphicItem::selfConnectAnchorPoints() const
{
    QList<QPointF> ret;

    ret << QPointF(25.0, -20) << QPointF(70.0, 25.0)
        << QPointF(25.0, 70.0) << QPointF(-20, 25.0);

    return ret;
}

bool SwpMergeGraphicItem::containsSameConnection(
    const ConnectionData& connection,
    const QList<ConnectionData>& connections) const
{
    bool ret = false;

    foreach (const ConnectionData& _connection, connections)
    {
        if (ConnectionComparator::compare(connection, _connection,
            ConnectionComparator::WithoutConnector))
        {
            ret = true;
            break;
        }
    }

    return ret;
}

int SwpMergeGraphicItem::incomingConnectionSize(
    const QList<ConnectionData>& connections) const
{
    int ret = 0;

    foreach (const ConnectionData& _connection, connections)
    {
        if (_connection.To == this)
        {
            ++ret;
        }
    }

    return ret;
}

int SwpMergeGraphicItem::outgoingConnectionSize(
    const QList<ConnectionData>& connections) const
{
    int ret = 0;

    foreach (const ConnectionData& _connection, connections)
    {
        if (_connection.From == this)
        {
            ++ret;
        }
    }

    return ret;
}
